package pl.polidea.imf.blackberry.service;

import java.io.IOException;
import java.util.Enumeration;

import pl.polidea.imf.blackberry.util.TIME_PERIODS;
import pl.polidea.imf.blackberry.util.ThreadHelper;
import pl.polidea.imf.common.java.http.requests.ServerCommunicationError;
import pl.polidea.imf.common.java.impl.storage.FileLogStream;
import pl.polidea.imf.common.java.model.ConditionReq;
import pl.polidea.imf.common.java.model.IssueReportReq;
import pl.polidea.imf.common.java.model.LogReportReq;
import pl.polidea.imf.common.java.net.CommunicationManager;
import pl.polidea.imf.common.java.storage.JSONItemStorage;

public class NetworkWorkerThread extends Thread {

	private volatile boolean isRunning = true;
	final private CommunicationManager communicationManager;

	final private JSONItemStorage logStorage;
	final private JSONItemStorage issueStorage;
	final private JSONItemStorage conditionStorage;
	final private String sessionKey;

	public NetworkWorkerThread(CommunicationManager communicationManager, JSONItemStorage logStorage, JSONItemStorage issueStorage, JSONItemStorage conditionStorage, String sessionKey) {

		if (communicationManager == null) {
			throw new IllegalArgumentException("communication manager cannot be null");
		}
		if (sessionKey == null) {
			throw new IllegalArgumentException("sessionKey cannot be null");
		}

		this.communicationManager = communicationManager;
		this.logStorage = logStorage;
		this.issueStorage = issueStorage;
		this.conditionStorage = conditionStorage;
		this.sessionKey = sessionKey;
	}

	public void run() {
		// TODO: add big try catch
		while (isRunning) {
			ThreadHelper.tryToSleep(TIME_PERIODS.ONE_MINUTE);
			sendOut();
		}
	}

	public synchronized void stopWorker() {
		isRunning = false;
	}

	public synchronized void cleanCache() {
		clearStorage(conditionStorage);
		clearStorage(issueStorage);
		clearStorage(logStorage);
	}

	private void clearStorage(JSONItemStorage storage) {
		if (storage == null) {
			return;
		}
		Enumeration items;
		try {
			items = storage.getLogStreams();

			while (items.hasMoreElements()) {
				FileLogStream logStream = (FileLogStream) items.nextElement();
				try {
					logStream.open();
					logStream.closeAndRemove();
				} catch (IOException e) {
					System.out.println("cannot delete: " + e);
				}
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	private synchronized void sendOut() {

		if (logStorage != null) {
			sendLogs();
		}
		if (issueStorage != null) {
			sendIssues();
		}
		if (conditionStorage != null) {
			sendConditions();
		}

	}

	private void sendIssues() {
		try {
			Enumeration issues = issueStorage.getLogStreams();
			while (issues.hasMoreElements()) {
				FileLogStream logStream = (FileLogStream) issues.nextElement();
				try {
					logStream.open();
					communicationManager.sendIssueReport(new IssueReportReq(sessionKey, logStream.getInputStream()));
					logStream.closeAndRemove();
				} catch (ServerCommunicationError e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void sendLogs() {
		try {
			Enumeration logs = logStorage.getLogStreams();
			while (logs.hasMoreElements()) {
				FileLogStream logStream = (FileLogStream) logs.nextElement();
				try {
					logStream.open();
					communicationManager.sendLogReport(new LogReportReq(IMFService.getInstance().getSessionKey(), logStream.getInputStream()));
					logStream.closeAndRemove();
				} catch (ServerCommunicationError e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void sendConditions() {
		try {
			Enumeration conditions = conditionStorage.getLogStreams();
			while (conditions.hasMoreElements()) {
				FileLogStream logStream = (FileLogStream) conditions.nextElement();
				try {
					logStream.open();
					communicationManager.sendConditionReport(new ConditionReq(IMFService.getInstance().getSessionKey(), logStream.getInputStream()));
					logStream.closeAndRemove();
				} catch (ServerCommunicationError e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
